package com.axend.vetwavve.helper

import android.graphics.Bitmap
import android.os.Environment
import android.util.Log
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import org.opencv.android.OpenCVLoader
import org.opencv.android.Utils
import org.opencv.core.Core
import org.opencv.core.Mat
import org.opencv.core.MatOfFloat
import org.opencv.core.MatOfInt
import org.opencv.core.Rect
import org.opencv.imgcodecs.Imgcodecs
import org.opencv.imgproc.Imgproc
import javax.security.auth.callback.Callback

class Motion2DetectHelper {

    init {
        if (OpenCVLoader.initLocal()) {
            Log.i("MotionDetectHelper", "OpenCV loaded successfully")
        } else {
            Log.e("MotionDetectHelper", "OpenCV initialization failed!")
        }
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////
    private var previousFrame: Mat? = null
    private var currentFrame: Mat? = null
    private var targetRect: Rect? = null
    private var frameCount = 0
    private var savePosition = 0

    constructor()

    constructor(rect: Rect) {
        this.targetRect = rect
    }

    /**
     * process Infrared Thermal Imaging Target Motion
     */
    fun processThermalImagingTargetMotion(
        p0: Bitmap?,
        threshValue: Double = 50.0,
        moveMaxValue: Int = 2500,
        callback: (Int,Boolean) -> Unit
    ): Bitmap? {

        previousFrame = previousFrame ?: Mat()
        currentFrame = currentFrame ?: Mat()

        frameCount++
        if (frameCount % 1 == 0) {
            // 在这里检查前一帧是否为空
            if (previousFrame!!.empty()) {//为空的话将当前帧赋值给他
                Utils.bitmapToMat(p0, previousFrame)
                return p0;
            }
            Utils.bitmapToMat(p0, currentFrame)

            // 在指定的矩形框中进行帧差法（小猫头部外圈的框框）
            val currentRoi = Mat(currentFrame, targetRect) //框框内当前图
            val previousRoi = Mat(previousFrame, targetRect) //框框内上一帧图

//            GlobalScope.launch(Dispatchers.Main) {
////                delay(10000) // 延迟 1000 毫秒（1 秒）
//                if (savePosition < 10) {
//                    // 保存 currentRoi 到文件
//                    Imgcodecs.imwrite(
//                        "${Environment.getExternalStorageDirectory().absolutePath}/currentRoi_$savePosition.png",
//                        currentRoi
//                    )
//
//                    // 保存 previousRoi 到文件
//                    Imgcodecs.imwrite(
//                        "${Environment.getExternalStorageDirectory().absolutePath}/previousRoi_$savePosition.png",
//                        previousRoi
//                    )
//                    savePosition++
//                }
//            }

            val diff = Mat() // 框框内差异图
            val currentRoiGray = Mat() // 框框内当前帧灰度图
            val previousRoiGray = Mat() // 框框内上一帧灰度图
            Imgproc.cvtColor(currentRoi, currentRoiGray, Imgproc.COLOR_RGBA2GRAY);
            Imgproc.cvtColor(previousRoi, previousRoiGray, Imgproc.COLOR_RGBA2GRAY);


            //////////////////////////////////////////////////////////////////////////////////////////
            //将差异图像 diff 二值化，忽略小变化，凸显比较明显的变化
            Imgproc.threshold(
                currentRoiGray,
                currentRoiGray,
                248.0,
                255.0,
                Imgproc.THRESH_BINARY
            )
//            val filename="${Environment.getExternalStorageDirectory().absolutePath}/diff.png"
//            if (!currentRoiGray.empty()){
//                Imgcodecs.imwrite(
//                    filename,
//                    currentRoiGray
//                )
//            }

            val numBrightPixels = Core.countNonZero(currentRoiGray)
            val totalPixels = currentRoiGray.total()
            val pro = numBrightPixels / totalPixels.toDouble()

            // 保存 currentRoi 到文件
//            if (numBrightPixels>300){

//            }
            // 将Mat转换为Bitmap
//            val bitmap = Bitmap.createBitmap(diff.cols(), diff.rows(), Bitmap.Config.ARGB_8888)
//            Utils.matToBitmap(diff, bitmap)
            //val movementRatio = movement.toDouble() / (targetRect.width * targetRect.height) //非零像素的占比(非零像素在矩形区域中的占比)
            /*true值代表出框*/
            if (numBrightPixels > 1000) {
                callback(numBrightPixels,false)
                Log.d("MotionDetectHelper", "有猫脸")
            }else{
                callback(numBrightPixels,true)
                Log.d("MotionDetectHelper", "无猫脸")
            }
            //////////////////////////////////////////////////////////////////////////////////////////


            diff.release()
            currentRoiGray.release()
            currentRoiGray.release()
            previousFrame!!.release()

            //更新前一帧为当前帧
            currentFrame!!.copyTo(previousFrame)
//            previousFrame = currentFrame!!.clone()
            currentFrame!!.release()
            Utils.bitmapToMat(p0, currentFrame)
            previousFrame!!.release()
            Utils.bitmapToMat(p0, previousFrame)
            return p0
        } else {
            currentFrame!!.release()
            Utils.bitmapToMat(p0, currentFrame)
            previousFrame!!.release()
            Utils.bitmapToMat(p0, previousFrame)
            return p0
        }
    }

    private fun findOptimalThreshold(diff: Mat): Double {
        val hist = Mat()
        val histSize = 256
        val range = MatOfFloat(0f, 256f)
        val channels = MatOfInt(0)
        val mask = Mat()

        // 计算直方图
        Imgproc.calcHist(listOf(diff), channels, mask, hist, MatOfInt(1), range)

        // 找到直方图中的峰值
        var maxVal = 0.0
        var optimalThreshold = 0.0
        for (i in 0 until histSize) {
            val value = hist.get(i, 0)[0]
            if (value > maxVal) {
                maxVal = value
                optimalThreshold = i.toDouble()
            }
        }

        return optimalThreshold
    }

    fun release() {
        previousFrame?.release()
        currentFrame?.release()
    }
    ////////////////////////////////////////////////////////////////////////////////////////////////
}
